/**
 * @file        storage.cpp
 * @brief       Storage management.
 *
 * @author      Emre Turkay <emreturkay at gmail>
 * @date        Jul.9.2008
 */

#include "storage.hpp"
#include "gtd.hpp"

namespace
{

    std::string get_home()
    {
#ifndef WIN32
        const char* home = getenv("HOME");
#else
	    const char* home = getenv("APPDATA");
#endif

        if (!home)
            throw std::runtime_error("HOME is not defined");

        return home;
    }

} // unnamed namespace

namespace gtd
{

storage::storage(gtd& object)
    : object_(object)
{
    std::string path = get_home() + "/gtd";
    todo_file_name_ = path + "/todo.txt";
    done_file_name_ = path + "/done.txt";
}

void storage::load()
{
    {
        std::ifstream f(todo_file_name_.c_str());
        if (!f)
            throw std::runtime_error(
                std::string("Could not open file: ") + todo_file_name_);

        while (!f.eof())
        {
            std::string line;
            std::getline(f, line);
            object_.append(line);
        }
    }

    {
        std::ifstream f(done_file_name_.c_str());
        if (!f)
            throw std::runtime_error(
                std::string("Could not open file: ") + done_file_name_);

        f.unsetf(std::ios::skipws);
        object_.load_done(f);
    }
}

void storage::save()
{
    save_todo();
    save_done();
}

void storage::save_todo()
{
    std::ofstream f(todo_file_name_.c_str());

    std::list<gtd::project_id> l = object_.project_ids();

    for (std::list<gtd::project_id>::const_iterator i = l.begin();
         i != l.end(); ++i)
    {
        const project& p = object_.get_project(*i);

        std::list<project::action_id> actions = p.items();

        for (std::list<project::action_id>::const_iterator j = actions.begin();
             j != actions.end(); ++j)
        {
            if (p.name())
                f << '+' << *(p.name()) << ' ';

            const action& a = p.item(*j);
            
            for (std::set<std::string>::const_iterator k = a.contexts().begin();
                 k != a.contexts().end(); ++k)
            {
                f << '@' << *k << ' ';
            }

            f << a.description() << std::endl;
        }
    }
}

void storage::save_done()
{
    std::ofstream f(done_file_name_.c_str());
    object_.save_done(f);
}

} // namespace gtd

